/* 事件总线 */
class EventBus {
    constructor(name) {
        this.name = name

        /* 
        {
            "体育":[
                {name:"王朝",callback:msg=>{...}},
                {name:"马汉",callback:msg=>{...}},
            ],
            "情感":[
                {...},
                {...}
            ]
        }
        */
        this.subscribers = {}

        /* 
        发布内容=>产生事件
        {
            "体育":["内容1","内容2"],
            "情感":["内容1","内容2"],
        }
        */
        this.events = {}
    }

    /* 平台接收订阅者 */
    subscribe(subscriber, subject, callback) {
        /* 如果主题未被创建 则先创建主题 */
        if (!this.subscribers[subject]) {
            this.subscribers[subject] = []
        }
        // console.log("this.subscribers", this.subscribers);
        this.subscribers[subject].push({ name: subscriber.name, callback })
    }

    /* 平台发布内容 */
    publish(publisher, subject, msg) {
        /* 如果主题未被创建 则先创建主题 */
        if (!this.events[subject]) {
            this.events[subject] = []
        }

        // 增加一条内容
        console.log("publish msg=", msg);
        const content = { name: publisher.name, subject, msg }
        this.events[subject].push(content)

        // 通知该主题的所有订阅者响应
        this.subscribers[subject].forEach(
            obj => obj.callback(content)
        )
    }
}

/* 发布者 */
class Publisher {
    constructor(name, platform) {
        this.name = name

        // 发布消息的平台
        this.platform = platform
    }

    /* 发布短视频 */
    publish(subject, msg) {
        // 通知平台发布事件
        this.platform.publish(this, subject, msg)
    }
}

/* 订阅者 */
class Subscriber {
    constructor(name, platform) {
        this.name = name

        // 订阅消息的平台
        this.platform = platform
    }

    /* 订阅=通知平台注册自己 */
    subscribe(subject, callback) {
        this.platform.subscribe(this, subject, callback)
    }
}

/* 业务逻辑 */
~function main() {
    const douyin = new EventBus("抖音")

    const zhanglong = new Publisher("张龙", douyin)
    const zhaohu = new Publisher("赵虎", douyin)

    const wangchao = new Subscriber("王超", douyin)
    const mahan = new Subscriber("马汉", douyin)

    wangchao.subscribe("体育", content => console.log(wangchao.name, "收看了", content))
    wangchao.subscribe("情感", content => console.log(wangchao.name, "收看了", content))
    mahan.subscribe("体育", content => console.log(mahan.name, "收看了", content, "并且喝了一杯"))
    mahan.subscribe("情感", content => console.log(mahan.name, "收看了", content, "并且跃跃欲试"))

    setTimeout(() => {
        zhanglong.publish("体育", "张志磊再次KO乔伊斯")
    }, 3000);

    setTimeout(() => {
        zhaohu.publish("情感", "西门大官人准备今晚在狮子楼开派对")
    }, 5000);

}()
